﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

using NngLevelEditor.Utility;
using NngLevelEditor.Manager;

namespace NngLevelEditor.Entities
{
    public class TileGrid : Entity
    {
        private List<Tile> _grid;

        private float _minTileX;
        private float _maxTileX;
        private float _minTileY;
        private float _maxTileY;

        private ContentManager _manager;

        public float MinTileX
        {
            get { return _minTileX; }
            set { ; }
        }

        public float MinTileY
        {
            get { return _minTileY; }
            set { ; }
        }

        public TileGrid()
        {
            _grid = new List<Tile>();
            _minTileX = float.MaxValue;
            _maxTileX = float.MinValue;
            _minTileY = float.MaxValue;
            _maxTileY = float.MinValue;
        }

        #region Grid Update

        protected void OnGridChange(Tile change)
        {

        }

        protected Vector2 AlignToGrid(Vector2 position)
        {
            Vector2 conversion = position.ToXnaUnits();
            int xCoefficient = (int)Math.Round((double)conversion.X / 64.0);
            int yCoefficient = (int)Math.Round((double)conversion.Y / 64.0);

            return (new Vector2(xCoefficient * 64.0f, yCoefficient * 64.0f)).ToWorldUnits();
        }

        #endregion

        #region Grid Management

        public void Add(Tile tile)
        {
            tile.Position = AlignToGrid(tile.Position);
            Tile removeTile = null;

            foreach (Tile t in _grid)
            {
                if (t.Position.Equals(tile.Position))
                {
                    removeTile = t;                    
                }
            }
            if (removeTile != null)
            {
                Remove(removeTile);
            }
            _grid.Add(tile);

            Vector2 xnaPosition = tile.Position.ToXnaUnits();

            _minTileX = (xnaPosition.X < _minTileX) ? xnaPosition.X : _minTileX;
            _minTileY = (xnaPosition.Y < _minTileY) ? xnaPosition.Y : _minTileY;

            _maxTileX = (xnaPosition.X > _maxTileX) ? xnaPosition.X : _maxTileX;
            _maxTileY = (xnaPosition.Y > _maxTileY) ? xnaPosition.Y : _maxTileY;

            if (_grid.Count > 1)
                OnGridChange(tile);
        }

        public bool Remove(Tile tile)
        {
            try
            {
                _grid.Remove(tile);
                OnGridChange(tile);
                ((Tile)tile).UnloadContent();
                return true;
            }
            catch
            {

            }

            return false;
        }

        public void Clear()
        {
            try
            {
                foreach (Tile tile in _grid)
                {
                    tile.UnloadContent();
                }

                _grid.Clear();
            }
            catch
            {

            }
        }

        public override string GetFileString()
        {
            int length = (int)((_maxTileX / 64) - (_minTileX / 64));
            int height = (int)((_maxTileY / 64) - (_minTileY / 64));
            String fileString = "<Asset>\n";
            fileString += "<Length>" + (length + 1) + "</Length>\n";
            fileString += "<Height>" + (height + 1) + "</Height>\n";

            foreach (Tile t in _grid)
            {
                fileString += t.GetXml(_minTileX, _minTileY);
            }

            return fileString + "</Asset>\n";
        }
        #endregion

        public bool DetectSelection(Vector2 clickPosition)
        {
            Vector2 selectionSize = new Vector2(32.0f, 32.0f);
            selectionSize = selectionSize.ToWorldUnits();

            foreach (Entity e in _grid)
            {
                Vector2 deltaPosition = e.Position - clickPosition;
                if (Math.Abs(deltaPosition.X) < (selectionSize.X) && Math.Abs(deltaPosition.Y) < (selectionSize.X))
                {
                    SelectionManager.SelectedEntity = e;
                    return true;
                }
            }

            return false;
        }
    }
}
